'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.init = exports.setGlobalData = exports.getGlobalData = exports.initGlobalData = undefined;

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _jsCookie = require('js-cookie');

var _jsCookie2 = _interopRequireDefault(_jsCookie);

var _simpleGet = require('../simpleGet');

var _simpleSet = require('../simpleSet');

var _ua = require('../mobile/ua');

var _fingerprintjs = require('fingerprintjs2');

var _fingerprintjs2 = _interopRequireDefault(_fingerprintjs);

var _device = require('../mobile/device');

var _murmurHash = require('../mobile/murmurHash3');

var _murmurHash2 = _interopRequireDefault(_murmurHash);

var _syncServer = require('./syncServer');

var _safeStringify = require('../safeStringify');

var _safeStringify2 = _interopRequireDefault(_safeStringify);

var _map = require('lodash/map');

var _map2 = _interopRequireDefault(_map);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Version = '1.0.0';
var finger = null;
var getDeviceFinger = function getDeviceFinger(cb) {
    if (finger) {
        cb(finger);
        return;
    }
    new _fingerprintjs2.default({
        excludeFlashFonts: true,
        excludeJsFonts: true
    }).get(function (_finger) {
        finger = _finger;
        cb(finger);
    });
};

var PType = {
    None: -1,
    Page: 1,
    Resource: 2,
    Paint: 3,
    Tag: 4
};
var getDefaultItem = function getDefaultItem() {
    return {
        p_type: PType.None,
        name: '',
        start_time: -1,
        type: '',
        initiator_type: '',
        duration: -1,
        redirect: -1,
        fetch_start: -1,
        dns: -1,
        tcp_connect: -1,
        secure_connect: -1,
        request: -1,
        response: -1,
        transfer_size: -1,
        encode_body_size: -1,
        decode_body_size: -1,

        unload_event: -1,
        dom_loading: -1,
        dom_interactive: -1,
        dom_content_loaded: -1,
        dom_complete: -1,
        load_event: -1,

        data: ''
    };
};

var PerformanceGlobalData = {
    global: {},
    template: Object.keys(getDefaultItem()),
    data: [],
    tags: []
};

var getInt = function getInt(obj, path, defVal) {
    return parseInt((0, _simpleGet.simpleGet)(obj, path, defVal));
};

var g = PerformanceGlobalData;
var p = window.performance;

var initGlobalData = exports.initGlobalData = function initGlobalData() {
    var cookie = _jsCookie2.default.get() || {};

    var os = _ua.ua.getOS();
    var browser = _ua.ua.getBrowser();
    var device = _ua.ua.getDevice();

    var data = {
        url: location.href || '',
        cookie: cookie.uuid || '',
        tags: g.tags.join(','),
        user_agent: navigator.userAgent || '',
        version: '',
        client: (0, _device.getDeviceString)(),
        device_finger: '',
        uuid: cookie.uuid || '',
        hash: '',

        os: '',
        os_version: os.name + ' ' + os.version,
        device: device.model + ' ' + device.vendor,
        browser: browser.name + ' ' + browser.version,

        time_origin: getInt(p, 'timeOrigin', -1),
        navigation_start: getInt(p, 'timing.navigationStart', -1) };

    return data;
};
var getGlobalData = exports.getGlobalData = function getGlobalData() {
    return Object.assign({}, g.global);
};

var getPageHash = function getPageHash() {
    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        _ref$url = _ref.url,
        url = _ref$url === undefined ? '' : _ref$url,
        tags = _ref.tags,
        user_agent = _ref.user_agent,
        device_finger = _ref.device_finger,
        time_origin = _ref.time_origin;

    var str = [url, tags, document.cookie, user_agent, device_finger, time_origin].join('@');
    return _murmurHash2.default.x64.hash128(str, 31);
};

var setGlobalData = exports.setGlobalData = function setGlobalData() {
    var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    Object.assign(g.global, data);
};

var sub = function sub() {
    var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var key1 = arguments[1];
    var key2 = arguments[2];

    var val1 = obj[key1] || 0;
    var val2 = obj[key2] || 0;
    return parseInt(val1) - parseInt(val2);
};

var defaultItem = getDefaultItem();

var fixItemData = function fixItemData(item) {
    var rst = {};
    var val = void 0;
    for (var key in defaultItem) {
        val = item[key];
        if (val === undefined || val === null) {
            rst[key] = defaultItem[key];
            continue;
        }
        if (typeof val === 'number') {
            val = parseInt(val);
        }
        rst[key] = val;
    }
    return rst;
};

var getNormalItem = function getNormalItem(item) {
    return {
        name: item.name,

        type: item.entryType,
        initiator_type: item.initiatorType,
        duration: item.duration,
        redirect: sub(item, 'redirectEnd', 'redirectStart'),
        fetch_start: p.timeOrigin + item.fetchStart,
        dns: sub(item, 'domainLookupEnd', 'domainLookupStart'),
        tcp_connect: sub(item, 'connectEnd', 'connectStart'),
        secure_connect: sub(item, 'connectEnd', 'secureConnectionStart'),
        request: sub(item, 'responseStart', 'requestStart'),
        response: sub(item, 'responseEnd', 'responseStart'),
        transfer_size: item.transferSize,
        encode_body_size: item.encodedBodySize,
        decode_body_size: item.decodedBodySize
    };
};

var getPageItem = function getPageItem() {
    var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    var timing = p.timing;
    return (0, _extends3.default)({
        p_type: PType.Page,
        start_time: p.timeOrigin

    }, getNormalItem(item), {

        unload_event: sub(item, 'unloadEventEnd', 'unloadEventStart'),
        dom_loading: timing.domLoading || -1,
        dom_interactive: sub(item, 'domInteractive', 'domLoading'),
        dom_content_loaded: sub(item, 'domContentLoadedEventEnd', 'domContentLoadedEventStart'),
        dom_complete: timing.domComplete || -1,
        load_event: sub(item, 'loadEventEnd', 'loadEventStart')
    });
};
var getResourceItem = function getResourceItem(item) {
    return (0, _extends3.default)({
        p_type: PType.Resource,
        start_time: p.timeOrigin + item.startTime

    }, getNormalItem(item));
};
var getPaintItem = function getPaintItem(item) {
    return {
        p_type: PType.Paint,
        name: item.name,
        start_time: p.timeOrigin + item.startTime,

        type: item.entryType,
        duration: item.duration
    };
};

var getTagItem = function getTagItem(item) {
    return {
        p_type: PType.Tag,
        name: item.name,
        start_time: item.startTime,

        type: item.type,
        duration: item.duration,
        data: item.data
    };
};

var getItem = function getItem(entry) {
    var _entry$entryType = entry.entryType,
        entryType = _entry$entryType === undefined ? '' : _entry$entryType;

    if (entryType === 'navigation') {
        return getPageItem(entry);
    }
    if (entryType === 'resource') {
        return getResourceItem(entry);
    }
    if (entryType === 'paint') {
        return getPaintItem(entry);
    }
};

var clearEntries = function clearEntries() {
    if (!performance.clearResourceTimings) {
        return;
    }
    performance.clearResourceTimings();
};
var getEntries = function getEntries() {
    if (!performance.getEntries) {
        return [];
    }
    return performance.getEntries();
};

var getEntriesByType = function getEntriesByType() {
    var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'resource';

    if (!performance.getEntriesByType) {
        return [];
    }
    return performance.getEntriesByType(type);
};
var entriesToItem = function entriesToItem(entries) {
    var rst = [];
    for (var i = 0; i < entries.length; i++) {
        rst.push(fixItemData(getItem(entries[i])));
    }
    return rst;
};

var firstRecord = true;
var cleanAndRecord = function cleanAndRecord() {
    var data = g.data;
    var newData = [];
    if (firstRecord) {
        newData = getEntries();
        firstRecord = false;
    } else {
        newData = getEntriesByType();
    }
    g.data = data.concat(entriesToItem(newData));
    clearEntries();
};
var cleanData = function cleanData() {
    console.log('cleanData:', g.data.length);
    g.data = [];
};

var _getServerData = function _getServerData() {
    var value = (0, _map2.default)(g.data, function (item) {
        return (0, _map2.default)(g.template, function (key) {
            return item[key];
        });
    });
    return {
        global: g.global,
        data: {
            template: g.template,
            value: value
        }
    };
};
var getServerData = function getServerData(getRequestArgs) {
    if (!firstRecord && g.data.length < 1) {
        return _syncServer.EmptyResult;
    }
    var requestArgs = {
        url: 'http://uc.maodou.com/prm',
        method: 'post',
        postType: 'json'
    };
    return {
        requestArgs: getRequestArgs(),

        data: _getServerData()
    };
};
var _getRequestArgs = function _getRequestArgs() {
    return {
        url: 'http://uc.maodou.com/prm',
        method: 'post',
        postType: 'json'
    };
};

var init = exports.init = function init() {
    var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        _ref2$getVersion = _ref2.getVersion,
        getVersion = _ref2$getVersion === undefined ? function () {
        return '';
    } : _ref2$getVersion,
        done = _ref2.done,
        _ref2$getRequestArgs = _ref2.getRequestArgs,
        getRequestArgs = _ref2$getRequestArgs === undefined ? _getRequestArgs : _ref2$getRequestArgs;

    setGlobalData(initGlobalData());
    getDeviceFinger(function (finger) {
        setGlobalData({
            'device_finger': finger
        });
        setGlobalData({
            'hash': getPageHash(getGlobalData()),
            'version': getVersion()
        });
        done && done(g);

        (0, _syncServer.syncToLocalStorage)({
            version: Version,
            key: 'performance_statistic',
            getData: function getData() {
                var data = getServerData(getRequestArgs);
                cleanData();
                return data;
            },
            checkConcat: function checkConcat(data, oldData) {
                var hash = (0, _simpleGet.simpleGet)(data, 'data.global.hash');
                var oldHash = (0, _simpleGet.simpleGet)(oldData, 'data.global.hash');
                return hash === oldHash;
            },
            concatData: function concatData(data, oldData) {
                var value = (0, _simpleGet.simpleGet)(data, 'data.data.value', []);
                var oldValue = (0, _simpleGet.simpleGet)(oldData, 'data.data.value', []);
                (0, _simpleSet.simpleSet)(data, 'data.data.value', oldValue.concat(value));
                return data;
            }
        });
        (0, _syncServer.syncToServer)({
            version: Version,
            cleanOldVersion: true,
            key: 'performance_statistic',
            interval: 7000
        });
    });
    var recordHandler = setInterval(function () {
        cleanAndRecord();
    }, 5000);

    var cancel = function cancel() {
        clearInterval(recordHandler);
    };

    return {
        cancel: cancel
    };
};